﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;


namespace XGame
{
    public class XboxController
    {
        private GamePadState currentGamePadState;


        public GamePadState CurrentGamePadState
        {
            get { return currentGamePadState; }
            set { currentGamePadState = value; }
        }


        private GamePadState previouseGamePadState;

        public GamePadState PreviouseGamePadState
        {
            get { return previouseGamePadState; }
            set { previouseGamePadState = value; }
        }

        private PlayerIndex controllerIndex;


        //Events for on pressed and released
        /// <summary>
        /// Triggered when A is Pressed
        /// </summary>
        public event EventHandler<EventArgs> aButtonPressed;
        /// <summary>
        /// Triggered when B is Pressed
        /// </summary>
        public event EventHandler<EventArgs> bButtonPressed;
        /// <summary>
        /// Triggered when X is Pressed
        /// </summary>
        public event EventHandler<EventArgs> xButtonPressed;
        /// <summary>
        /// Triggered when Y is Pressed
        /// </summary>
        public event EventHandler<EventArgs> yButtonPressed;
        /// <summary>
        /// Triggered when the Left Bumper is Pressed
        /// </summary>
        public event EventHandler<EventArgs> leftBumperPressed;
        /// <summary>
        /// Triggered when the Right Bumper is Pressed
        /// </summary>
        public event EventHandler<EventArgs> rightBumperPressed;
        
        /// <summary>
        /// Triggered when The Right Button On The D-Pad is Pressed
        /// </summary>
        public event EventHandler<EventArgs> DPadRightPressed;
        
        /// <summary>
        /// Triggered when The Left Button On The D-Pad is Pressed
        /// </summary>
        public event EventHandler<EventArgs> DPadLeftPressed;
        
        /// <summary>
        /// Triggered when The Down Button On The D-Pad is Pressed
        /// </summary>
        public event EventHandler<EventArgs> DPadDownPressed;
        
        /// <summary>
        /// Triggered when The Up Button On The D-Pad is Pressed
        /// </summary>
        public event EventHandler<EventArgs> DPadUpPressed;
        
        /// <summary>
        /// Triggered when The guide Button is pressed       
        /// </summary>
        public event EventHandler<EventArgs> XboxButtonPressed;
        
        /// <summary>
        /// Triggered when Back is Pressed
        /// </summary>
        public event EventHandler<EventArgs> BackButtonPressed;
        
        /// <summary>
        /// Triggered when Start is Pressed
        /// </summary>
        public event EventHandler<EventArgs> StartButtonPressed;

        /// <summary>
        /// Triggered when the Left Stick is pressed
        /// </summary>
        public event EventHandler<EventArgs> LeftStickPressed;

        /// <summary>
        /// Triggered when the Right Stick is Pressed
        /// </summary>
        public event EventHandler<EventArgs> RightStickPressed;

        public event EventHandler<EventArgs> aButtonReleased;
        public event EventHandler<EventArgs> bButtonReleased;
        public event EventHandler<EventArgs> xButtonReleased;
        public event EventHandler<EventArgs> yButtonReleased;
        public event EventHandler<EventArgs> leftBumperReleased;
        public event EventHandler<EventArgs> rightBumperReleased;
        public event EventHandler<EventArgs> DPadRightReleased;
        public event EventHandler<EventArgs> DPadLeftReleased;
        public event EventHandler<EventArgs> DPadDownReleased;
        public event EventHandler<EventArgs> DPadUpReleased;
        public event EventHandler<EventArgs> XboxButtonReleased;
        public event EventHandler<EventArgs> BackButtonReleased;
        public event EventHandler<EventArgs> StartButtonReleased;

        public event EventHandler<EventArgs> LeftStickReleased;
        public event EventHandler<EventArgs> RightStickReleased;

        public bool isAButtonPressed;
        public bool isBButtonPressed;
        public bool isXButtonPressed;
        public bool isYButtonPressed;
        public bool isRBButtonPressed;
        public bool isLBButtonPressed;

        public bool isDPadRightPressed;
        public bool isDPadLeftPressed;
        public bool isDPadDownPressed;
        public bool isDPadUpPressed;

        public bool isXboxButtonPressed;
        public bool isBackButtonPressed;
        public bool isStartButtonPressed;

        public bool isLeftStickDown;
        public bool isRightStickDown;

        public Vector2 LeftStickPosition
        {
            get { return currentGamePadState.ThumbSticks.Left; }
        }

        public Vector2 RightStickPosition
        {
            get { return currentGamePadState.ThumbSticks.Right; }
        }

        public float LeftStickLength
        {
            get { return currentGamePadState.ThumbSticks.Left.Length(); }
        }

        public float RightStickLength
        {
            get { return currentGamePadState.ThumbSticks.Right.Length(); }
        }

        public float LeftTriggerPosition
        {
            get { return currentGamePadState.Triggers.Left; }
        }

        public float RightTriggerPosition
        {
            get { return currentGamePadState.Triggers.Right; }
        }

       

        //A timer for how long the rumble timer is
        private Timer RumbleTimer;

        public XboxController(PlayerIndex Index)
        {
            controllerIndex = Index;
            RumbleTimer = new Timer();
            RumbleTimer.onTimerComplete += stopRumble;

            
        }

        #region  protected 
        protected internal void aPressed(EventArgs e)
        {
            if (aButtonPressed != null)
                aButtonPressed(this, EventArgs.Empty);
            isAButtonPressed = true;
        }

        protected internal void bPressed(EventArgs e)
        {
            if (bButtonPressed != null)
                bButtonPressed(this, EventArgs.Empty);
            isBButtonPressed = true;
        }

        protected internal void xPressed(EventArgs e)
        {
            if (xButtonPressed != null)
                xButtonPressed(this, EventArgs.Empty);
            isXButtonPressed = true;
        }

        protected internal void yPressed(EventArgs e)
        {
            if (yButtonPressed != null)
                yButtonPressed(this, EventArgs.Empty);
            isYButtonPressed = true;
        }

        protected internal void LBPressed(EventArgs e)
        {
            if (leftBumperPressed != null)
                leftBumperPressed(this, EventArgs.Empty);
            isLBButtonPressed = true;
        }

        protected internal void RBPressed(EventArgs e)
        {
            if (rightBumperPressed != null)
                rightBumperPressed(this, EventArgs.Empty);
            isRBButtonPressed = true;
        }

        protected internal void DUpPressed(EventArgs e)
        {
            if (DPadUpPressed != null)
                DPadUpPressed(this, EventArgs.Empty);
            isDPadUpPressed = true;
        }

        protected internal void DDownPressed(EventArgs e)
        {

            if (DPadDownPressed != null)
                DPadDownPressed(this, EventArgs.Empty);
            isDPadDownPressed = true;
        }

        protected internal void DLeftLPressed(EventArgs e)
        {

            if (DPadLeftPressed != null)
                DPadLeftPressed(this, EventArgs.Empty);
            isDPadLeftPressed = true;
        }


        protected internal void RightBumperPressed(EventArgs e)
        {
            if (rightBumperPressed != null)
                rightBumperPressed(this, EventArgs.Empty);
            isRBButtonPressed = true;
        }

        protected internal void BackPressed(EventArgs e)
        {
            if (BackButtonPressed != null)
                BackButtonPressed(this, EventArgs.Empty);
            isBackButtonPressed = true;
        }

        protected internal void StartPressed(EventArgs e)
        {

            if (StartButtonPressed != null)
                StartButtonPressed(this, EventArgs.Empty);
            isDPadDownPressed = true;
        }

        protected internal void XboxLeftPressed(EventArgs e)
        {

            if (XboxButtonPressed != null)
                XboxButtonPressed(this, EventArgs.Empty);
            isXboxButtonPressed = true;
        }

        protected internal void LeftPressed(EventArgs e)
        {

            if (LeftStickPressed != null)
                LeftStickPressed(this, EventArgs.Empty);
            isLeftStickDown = true;
        }

        protected internal void RightPressed(EventArgs e)
        {

            if (RightStickPressed != null)
                RightStickPressed(this, EventArgs.Empty);
            isRightStickDown = true;
        }
        #endregion


        public void Update(GameTime gameTime)
        {
            currentGamePadState = GamePad.GetState(controllerIndex);


            ///////////////////////////////////////////////////////////
            //Face Buttons
            ///////////////////////////////////////////////////////////

            ////////////////////////
            //A Button Stuff
            ////////////////////////
            if (currentGamePadState.Buttons.A == ButtonState.Pressed &&
                previouseGamePadState.Buttons.A == ButtonState.Released)
            {
                if (aButtonPressed != null)
                    aButtonPressed(this, EventArgs.Empty);
                isAButtonPressed = true;
            }

            if (currentGamePadState.Buttons.A == ButtonState.Released &&
               previouseGamePadState.Buttons.A == ButtonState.Pressed)
            {
                if (aButtonReleased != null)
                    aButtonReleased(this, EventArgs.Empty);
                isAButtonPressed = false;
            }
            ////////////////////
            //B Button Stuff
            ////////////////////
            if (currentGamePadState.Buttons.B == ButtonState.Pressed &&
                previouseGamePadState.Buttons.B == ButtonState.Released)
            {

                if (bButtonPressed != null)
                    bButtonPressed(this, EventArgs.Empty);
                isBButtonPressed = true;   

            }

            if (currentGamePadState.Buttons.B == ButtonState.Released &&
               previouseGamePadState.Buttons.B == ButtonState.Pressed)
            {

                if (bButtonReleased != null)
                    bButtonReleased(this, EventArgs.Empty);
                isBButtonPressed = false;

            }
            ////////////////////
            //X Button Stuff
            ////////////////////
            if (currentGamePadState.Buttons.X == ButtonState.Pressed &&
                previouseGamePadState.Buttons.X == ButtonState.Released)
            {
                if (xButtonPressed != null)
                    xButtonPressed(this, EventArgs.Empty);
                isXButtonPressed = true;

            }

            if (currentGamePadState.Buttons.X == ButtonState.Released &&
                previouseGamePadState.Buttons.X == ButtonState.Pressed)
            {
                if (xButtonReleased != null)
                    xButtonReleased(this, EventArgs.Empty);
                isXButtonPressed = false;

            }


            ///////////////////
            //Y Button Stuff
            ///////////////////
            if (currentGamePadState.Buttons.Y == ButtonState.Pressed &&
                previouseGamePadState.Buttons.Y == ButtonState.Released)
            {
                if (yButtonPressed != null)
                    yButtonPressed(this, EventArgs.Empty);
                isYButtonPressed = true;

            }
            if (currentGamePadState.Buttons.X == ButtonState.Released &&
                previouseGamePadState.Buttons.X == ButtonState.Pressed)
            {
                if (yButtonReleased != null)
                    yButtonReleased(this, EventArgs.Empty);
                isYButtonPressed = false;

            }
            ////////////////////////////////////////////////////////////
            //Shoulder Buttons
            ////////////////////////////////////////////////////////////
            if (currentGamePadState.Buttons.LeftShoulder == ButtonState.Pressed &&
                previouseGamePadState.Buttons.LeftShoulder == ButtonState.Released)
            {
                if (leftBumperPressed != null)
                    leftBumperPressed(this, EventArgs.Empty);
                isLBButtonPressed = true;

            }

            if (currentGamePadState.Buttons.LeftShoulder == ButtonState.Released &&
                previouseGamePadState.Buttons.LeftShoulder == ButtonState.Pressed)
            {

                if (leftBumperReleased != null)
                    leftBumperReleased(this, EventArgs.Empty);
                isLBButtonPressed = false;

            }

            if (currentGamePadState.Buttons.RightShoulder == ButtonState.Pressed &&
                previouseGamePadState.Buttons.RightShoulder == ButtonState.Released)
            {

                if (rightBumperPressed != null)
                    rightBumperPressed(this, EventArgs.Empty);
                isRBButtonPressed = true;

            }

            if (currentGamePadState.Buttons.RightShoulder == ButtonState.Released &&
                previouseGamePadState.Buttons.RightShoulder == ButtonState.Pressed)
            {

                if (rightBumperReleased != null)
                    rightBumperReleased(this, EventArgs.Empty);
                isRBButtonPressed = false;

            }

            ///////////////////////////////////////////////////////////
            //Other Buttons
            ///////////////////////////////////////////////////////////
            if (currentGamePadState.Buttons.Back == ButtonState.Pressed &&
                previouseGamePadState.Buttons.Back == ButtonState.Released)
            {
                if (BackButtonPressed != null)
                    BackButtonPressed(this, EventArgs.Empty);
                isBackButtonPressed = true;
            }

            if (currentGamePadState.Buttons.Back == ButtonState.Released &&
                previouseGamePadState.Buttons.Back == ButtonState.Pressed)
            {
                if (BackButtonReleased != null)
                    BackButtonReleased(this, EventArgs.Empty);
                isBackButtonPressed = false;
            }

            if (currentGamePadState.Buttons.BigButton == ButtonState.Pressed &&
                previouseGamePadState.Buttons.BigButton == ButtonState.Released)
            {
                if (XboxButtonPressed != null)
                    XboxButtonPressed(this, EventArgs.Empty);
                isXboxButtonPressed = true;
            }

            if (currentGamePadState.Buttons.BigButton == ButtonState.Released &&
                previouseGamePadState.Buttons.BigButton == ButtonState.Pressed)
            {
                if (XboxButtonReleased != null)
                    XboxButtonReleased(this, EventArgs.Empty);
                isXboxButtonPressed = false;

            }

            if (currentGamePadState.Buttons.Start == ButtonState.Pressed &&
                previouseGamePadState.Buttons.Start == ButtonState.Released)
            {

                if (StartButtonPressed != null)
                    StartButtonPressed(this, EventArgs.Empty);
                isStartButtonPressed = true;

            }

            if (currentGamePadState.Buttons.Start == ButtonState.Released &&
               previouseGamePadState.Buttons.Start == ButtonState.Pressed)
            {
                if(StartButtonReleased != null)
                    StartButtonReleased(this, EventArgs.Empty);
                isStartButtonPressed = false;
            }
            //////////////////////////////////////////////////////////
            //D-Pad button States
            //////////////////////////////////////////////////////////
            if (currentGamePadState.DPad.Up == ButtonState.Pressed &&
                previouseGamePadState.DPad.Up == ButtonState.Released)
            {
                if (DPadUpPressed != null)
                    DPadUpPressed(this, EventArgs.Empty);
                isDPadUpPressed = true;

            }
            if (currentGamePadState.DPad.Up == ButtonState.Released &&
                previouseGamePadState.DPad.Up == ButtonState.Pressed)
            {
                if (DPadUpReleased != null)
                    DPadUpReleased(this, EventArgs.Empty);
                isDPadUpPressed = false;

            }

            if (currentGamePadState.DPad.Down == ButtonState.Pressed &&
               previouseGamePadState.DPad.Down == ButtonState.Released)
            {
                if (DPadDownPressed != null)
                    DPadDownPressed(this, EventArgs.Empty);
                isDPadDownPressed = true;


            }

            if (currentGamePadState.DPad.Down == ButtonState.Released &&
               previouseGamePadState.DPad.Down == ButtonState.Pressed)
            {
                if (DPadDownReleased != null)
                    DPadDownReleased(this, EventArgs.Empty);
                isDPadUpPressed = false;


            }

            if (currentGamePadState.DPad.Left == ButtonState.Pressed &&
               previouseGamePadState.DPad.Left == ButtonState.Released)
            {
                if (DPadLeftPressed != null)
                    DPadLeftPressed(this, EventArgs.Empty);
                isDPadLeftPressed = true;

            }

            if (currentGamePadState.DPad.Left == ButtonState.Released &&
               previouseGamePadState.DPad.Left == ButtonState.Pressed)
            {
                if (DPadLeftReleased != null)
                    DPadLeftReleased(this, EventArgs.Empty);
                isDPadLeftPressed = false;

            }

            if (currentGamePadState.DPad.Right == ButtonState.Pressed &&
               previouseGamePadState.DPad.Right == ButtonState.Released)
            {
                if (DPadRightPressed != null)
                    DPadRightPressed(this, EventArgs.Empty);
                isDPadRightPressed = true;

            }

            if (currentGamePadState.DPad.Right == ButtonState.Released &&
               previouseGamePadState.DPad.Right == ButtonState.Pressed)
            {
                if (DPadRightReleased != null)
                    DPadRightReleased(this, EventArgs.Empty);
                isDPadRightPressed = false;

            }

            //////////////////////////////////////
            //Left Stick and Right Stick events
            //////////////////////////////////////

            if (currentGamePadState.Buttons.LeftStick == ButtonState.Pressed &&
                previouseGamePadState.Buttons.LeftStick == ButtonState.Released)
            {
                if (LeftStickPressed != null)
                    LeftStickPressed(this, EventArgs.Empty);
                isLeftStickDown = true;

            }
            if (currentGamePadState.Buttons.LeftStick == ButtonState.Released &&
                previouseGamePadState.Buttons.LeftStick == ButtonState.Pressed)
            {
                if (LeftStickReleased != null)
                    LeftStickReleased(this, EventArgs.Empty);
                isLeftStickDown = false;


            }

            if (currentGamePadState.Buttons.LeftStick == ButtonState.Pressed &&
                previouseGamePadState.Buttons.LeftStick == ButtonState.Released)
            {
                if (RightStickPressed != null)
                    RightStickPressed(this, EventArgs.Empty);
                isRightStickDown = true;


            }
            if (currentGamePadState.Buttons.LeftStick == ButtonState.Released &&
                previouseGamePadState.Buttons.LeftStick == ButtonState.Pressed)
            {
                if (RightStickReleased != null)
                    RightStickReleased(this, EventArgs.Empty);
                isRightStickDown = false;


            }

            previouseGamePadState = currentGamePadState;

            //Update the rumble timer
            RumbleTimer.Update(gameTime);

        }//end Update Function

        public void startRumble(double TimerLength, float leftMotorStrength, float rightMotorStrength)
        {
            RumbleTimer.Start(TimerLength);
            GamePad.SetVibration(this.controllerIndex, leftMotorStrength, rightMotorStrength);

        }

        private void stopRumble(object sender, EventArgs e)
        {
            GamePad.SetVibration(this.controllerIndex, 0.0f, 0.0f);
        }

    }
}
